package com.wangzhenyu.learn.test.kotlin.volatile_

//synchronized
//某一个线程进入synchronized代码块前后，执行过程如下
//线程获得锁
//清空工作内存
//从主内存拷贝共享变量最新的值到工作内存成为副本
//执行代码
//将修改后的副本的值刷新回主内存中
//线程释放锁


//volatile
//禁止重排序(修饰变量后该变量无法重排序)
//线程A和B，线程A写入volatile变量temp（临界资源），接着线程B读取了temp，那么，线程A写入temp及之前的写操作都对线程B可见（线程A和线程B可以是同一个线程）
//volatile可以作为刷新之前变量的触发器，我们可以将某个变量设置为volatile修饰，
//其他线程一旦发现该变量修改的值后，触发获取到的该变量之前的操作都将是最新的且可见

//写volatile变量时，无论前一个操作是什么，都不能重排序
//读volatile变量时，无论后一个操作是什么，都不能重排序
//当先写volatile变量，后读volatile变量时，不能重排序

//count++ 操作不是一个原子性操作，也就是说在某一个时刻对某一个操作的执行，有可能被其他线程打断
//该操作的步骤 1.从主内存中读取数据到工作内存 2.对工作内存中的数据进行++操作 3.将工作内存中的数据写回主内存

//happens-before:前一个操作的结果可以被后续的操作获取，讲直白点就是前面一个操作变量a赋值为1，那后面一个操作肯定能知道a已经变成了1
//规则
//①
//程序顺序规则（单线程规则）一个线程中的每个操作，happens-before于该线程中的任意后续操作
//(同一个线程中前面的所有写操作对后面的操作可见)
//②
//锁规则（Synchronized,lock等）对一个锁的解锁，happens-before于随后对这个锁的加锁
//（如果线程1解锁了monitor a，接着线程2锁定了a。那么，线程1解锁a之前的写操作都对线程2可见，线程1和线程2可以是同一个线程）
//③
//volatile变量规则
//对一个volatile域的写，happens-before于任意对这个volatile域的读
//如果线程1写入volatile变量v（临界资源），接着线程2读取了v，那么，线程1写入v及之前的写操作都对线程2可见（线程1和线程2可以是同一个线程）
//④
//传递性
//如果A happens-before B，且 B happens-before C，那么A happens-before C
//⑤
//start()规则
//如果线程A执行操作ThreadB.start()(启动线程B)，那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作
//假定线程A在执行过程中，通过执行ThreadB.start()来启动线程B，那么线程A对共享变量的修改在接下来线程B开始执行前对线程B可见。注意，线程B启动后，线程A再对变量修改线程B未必可见
//⑥
//join()规则
//如果线程A在执行过程中，通过执行Thread.join()并成功返回，那么线程B中的任意操作Happens-before于线程A从Thread.join()操作成功返回
//线程1写入所有变量，在任意其他线程2调用t1.join()，或者t1.isAlive()成功返回后，都对t2可见

@Suppress("UNUSED")
object InstanceVolatile {

    var count: Int = 0



}